<template>
  <el-select
    ref="selectRef"
    v-model="modelValue"
    class="select"
    :allow-create="props.allowCreate"
    :disabled="inputDisabled"
    :filterable="props.allowCreate || props.filterable"
    :placeholder="calcPlaceholder"
    @change="handleChange"
    clearable
  >
    <el-option
      v-for="item in options"
      :key="item.key"
      :value="item.key"
      :label="item.value"
      :disabled="item.disabled === true"
    />
  </el-select>
</template>

<script setup>
import { ref, watch, computed } from 'vue';
import { useDisabled } from 'element-plus';

const modelValue = defineModel();
const emit = defineEmits(['change']);
const props = defineProps({
  options: [Array, String],
  allowCreate: {
    type: Boolean,
    default: false
  },
  filterable: {
    type: Boolean,
    default: true
  },
  placeholder: {
    type: String,
    default: '--请选择--'
  }
});

const selectRef = ref();
const options = ref([]);
const inputDisabled = useDisabled();

const init = (data) => {
  if (data) {
    if (Array.isArray(data)) {
      options.value = data;
    } else if (data === 'clear.options') {
      options.value = [];
    } else if (typeof data === 'string') {
      const optionList = [];
      data.split(',').forEach(item => {
        optionList.push({key: item, value: item});
      });
      options.value = optionList;
    }
  }

  if (modelValue.value
      && props.allowCreate
      && options.value.findIndex(item => item.key === modelValue.value) < 0) {
    options.value.push({key: modelValue.value, value: modelValue.value});
  }
};

const handleChange = (value) => {
  if (value
    && props.allowCreate
    && options.value.findIndex(item => item.key === value) < 0) {
    options.value.push({key: value, value: value});
  }

  let key = [], resultKey = [], resultValue = [];
  if (value && options.value) {
    key = [value];

    options.value.forEach(item => {
      if (key.indexOf(item.key) >= 0) {
        resultKey.push(item.key);
        resultValue.push(item.value);
      }
    });
  }

  emit('change', resultKey.join(','), resultValue.join(','));
};

const calcPlaceholder = computed(() => {
  return inputDisabled.value === true ? '' : props.placeholder;
});

watch(() => props.options, (data) => {
  init(data);
}, {immediate: true});
</script>

<style scoped>
.select {
  width: 100%;
}
</style>